// 放置一些全局性的杂项数据（如果某一类数据比较多，建议新开切片）
import { LOCAL_KEY_EDA, LOCAL_KEY_IOSM, LOCAL_KEY_SC } from '@/config/const-item';
import type { PayloadAction } from '@reduxjs/toolkit';
import { createSlice } from '@reduxjs/toolkit';
import { cloneDeep } from 'lodash';

interface IGlobalMask {
  /** 是否展示遮罩 */
  show: boolean;
  /** 展示类型（fullscreen-全屏，app-仅限于主要内容区域） */
  type?: 'fullscreen' | 'app';
  /** 说明文字 */
  text?: string;
}

interface IExtraDisplayArea {
  header: boolean;
  menu: boolean;
}

interface IInitState {
  /** 是否展示本地token输入框 */
  showLocalToken: boolean;
  /** 是否展示全局遮罩 */
  globalMask: IGlobalMask;
  /** 要展示的额外内容区域 */
  displayArea: IExtraDisplayArea;
  /** 是否只展示内容区域，生效等级高于displayArea */
  isOnlyMain: boolean;
  /** 样式相关配置 */
  styleCfg: {
    /** 主题色 */
    primaryColor: string;
    /** 主题类型 */
    themeType: 'dark' | 'light';
  };
  /** 菜单是否读取完毕 */
  isMenuLoaded: boolean;
}

/** 默认-额外展示区域 */
const defaultDisplayArea = { header: true, menu: true };
/** 默认-样式 */
const defaultStyle = { primaryColor: '#814629', themeType: 'light' };

// 根据 localStorage 恢复历史数据
const hisDisplayAreaStr = localStorage.getItem(LOCAL_KEY_EDA);
let hisDisplayArea: IExtraDisplayArea;
try {
  hisDisplayArea = hisDisplayAreaStr ? JSON.parse(hisDisplayAreaStr) : defaultDisplayArea;
} catch (error) {
  hisDisplayArea = defaultDisplayArea;
}

const hisStyleCfg = localStorage.getItem(LOCAL_KEY_SC);
let hisStyle: any;
try {
  hisStyle = hisStyleCfg ? JSON.parse(hisStyleCfg) : defaultStyle;
} catch (error) {
  hisStyle = defaultStyle;
}

// 初始值
const initialState: IInitState = {
  showLocalToken: false,
  globalMask: {
    show: false,
    type: 'app',
  },
  displayArea: hisDisplayArea,
  isOnlyMain: localStorage.getItem(LOCAL_KEY_IOSM) === 'true',
  styleCfg: hisStyle,
  isMenuLoaded: false,
};

// 创建切片
const currentSlice = createSlice({
  name: 'global',
  initialState,
  reducers: {
    setShowLocalToken: (state, action: PayloadAction<boolean>) => {
      state.showLocalToken = action.payload;
    },
    setGlobalMask: (state, action: PayloadAction<IGlobalMask>) => {
      // 如果是关闭遮罩，则将 提示内容 删除，防止影响到下一次的遮罩
      state.globalMask = {
        ...state.globalMask,
        ...action.payload,
        text: action.payload.show ? action.payload.text : '',
      };
    },
    setDisplayArea: (state, action: PayloadAction<IExtraDisplayArea | string[] | string>) => {
      let cpDisplayArea = cloneDeep(state.displayArea);
      const _p = action.payload;

      if (typeof _p === 'string') {
        cpDisplayArea[_p] = !cpDisplayArea[_p];
      } else if (Array.isArray(_p)) {
        for (let key of _p) {
          cpDisplayArea[key] = !cpDisplayArea[key];
        }
      } else {
        cpDisplayArea = action.payload as IExtraDisplayArea;
      }

      state.displayArea = cpDisplayArea;
      localStorage.setItem(LOCAL_KEY_EDA, JSON.stringify(cpDisplayArea));
    },
    setIsOnlyMain: (state, action: PayloadAction<boolean | boolean>) => {
      state.isOnlyMain = !!action.payload;
      localStorage.setItem(LOCAL_KEY_IOSM, String(!!action.payload));
    },
    setStyle: (state, action: PayloadAction<any>) => {
      const nextStyle = {
        ...state.styleCfg,
        ...action.payload,
      };
      state.styleCfg = nextStyle;
      localStorage.setItem(LOCAL_KEY_SC, JSON.stringify(nextStyle));
    },
    setMenuLoaded: (state, action: PayloadAction<boolean>) => {
      state.isMenuLoaded = action.payload;
    },
  },
});

// 用于redux注册的
export default currentSlice.reducer;

// @reduxjs/toolkit会自动生成action，外部调用这个就行
export const {
  setShowLocalToken,
  setGlobalMask,
  setDisplayArea,
  setIsOnlyMain,
  setStyle,
  setMenuLoaded,
} = currentSlice.actions;
